#ifndef CNP_HPP
#define CNP_HPP

#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/topic/Topic.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/publisher/qos/DataWriterQos.hpp>
#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/core/LoanableSequence.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include <string>
#include <functional>

#include "CnpMsgPubSubTypes.hpp"

// 定义跨平台导出宏
#if defined(_WIN32) || defined(_WIN64)
 #define CNP_API __declspec(dllexport)
#else
 #define CNP_API __attribute__((visibility("default")))
#endif

// 定义导出宏，用于Windows平台
//#define CNP_API __declspec(dllexport)

enum class CNP_RESULT {
    CNP_CLIENT_NOT_CONNECTED,
    CNP_CLIENT_CONNECTED,
    CNP_SUBSCRIBE_SUCCESS,
    CNP_SUBSCRIBE_FAILED,
    CNP_PUBLISH_SUCCESS,
    CNP_PUBLISH_FAILED,
    CNP_ERROR
    , CNP_DESTROY_CLIENT_FAILED, // 销毁客户端失败
    CNP_DESTROY_SERVER_FAILED, // 销毁服务器失败
    CNP_DESTROY_MSG_FAILED,    // 销毁消息对象失败
    CNP_DESTROY_ALREADY_DONE,  // 尝试多次销毁对象
    CNP_CLIENT_NULL,  // 客户端指针为空
    CNP_SERVER_NULL,  // 服务端指针为空
    CNP_MSG_NULL,     // 消息指针为空
    CNP_CALLBACK_NULL, // 回调函数指针为空
};

typedef int CNP_INT_32;
typedef int CNP_DOMAIN_ID;

typedef std::function<void(const CnpMsg&)> CmdRequestCallback;
typedef std::function<void(const CnpMsg&)> CmdResponseCallback;
typedef std::function<void(const CnpMsg&)> EventCallback;
typedef std::function<void(const CnpMsg&)> StatusCallback;

// 模板类用于通用的 DataReaderListener
template<typename DataType>
class CustomDataReaderListener : public eprosima::fastdds::dds::DataReaderListener {
public:
    using CallbackType = std::function<void(const DataType&)>;

    explicit CustomDataReaderListener(CallbackType callback) : callback_(callback) {}

    void on_data_available(eprosima::fastdds::dds::DataReader* reader) override {
        eprosima::fastdds::dds::LoanableSequence<DataType> data_values;
        eprosima::fastdds::dds::SampleInfoSeq sample_infos;
        if (reader->take(data_values, sample_infos) == eprosima::fastdds::dds::RETCODE_OK) {
            for (size_t i = 0; i < data_values.length(); ++i) {
                if (sample_infos[i].valid_data) {
                    callback_(data_values[i]);
                }
            }
            reader->return_loan(data_values, sample_infos);
        }
    }

private:
    CallbackType callback_;
};

// 指令请求监听器类 
class CNP_API CmdRequestListener : public CustomDataReaderListener<CnpMsg> {
public:
    explicit CmdRequestListener(CallbackType callback) : CustomDataReaderListener<CnpMsg>(callback) {}
};

// 事件监听器类
class CNP_API EventListener : public CustomDataReaderListener<CnpMsg> {
public:
    explicit EventListener(CallbackType callback) : CustomDataReaderListener<CnpMsg>(callback) {}
};

// 定义 CNPServer 类
class CNP_API CNPServer {
public:
    explicit CNPServer(CNP_DOMAIN_ID domain, const std::string& serverAppID);
    ~CNPServer();

    CNP_RESULT subscribeCmdRequest(CmdRequestCallback callback);
    CNP_RESULT subscribeEvent(EventCallback callback);
 
    CNP_RESULT publishCmdResponse(CnpMsg& cmd_return_data);
    CNP_RESULT publishStatus(CnpMsg& status_data);
    CNP_RESULT publishEvent(CnpMsg& event_data);

private:
    eprosima::fastdds::dds::DomainParticipant* participant_;

    eprosima::fastdds::dds::Subscriber* cmd_request_subscriber_;
    eprosima::fastdds::dds::Subscriber* event_subscriber_;

    eprosima::fastdds::dds::Publisher* status_publisher_;
    eprosima::fastdds::dds::Publisher* event_publisher_;
    eprosima::fastdds::dds::Publisher* cmd_response_publisher_;

    eprosima::fastdds::dds::DataReader* cmd_request_reader_;
    eprosima::fastdds::dds::DataReader* event_reader_;
    eprosima::fastdds::dds::DataWriter* status_writer_;
    eprosima::fastdds::dds::DataWriter* event_writer_;
    eprosima::fastdds::dds::DataWriter* cmd_response_writer_;

    eprosima::fastdds::dds::Topic* status_topic_;
    eprosima::fastdds::dds::Topic* event_topic_;
    eprosima::fastdds::dds::Topic* cmd_response_topic_;
    eprosima::fastdds::dds::Topic* cmd_request_topic_;

    std::string serverAppID_; // 新增：服务器应用程序ID
    eprosima::fastdds::dds::TypeSupport type_;

    // 回调函数
    CmdRequestCallback cmd_request_callback_;
    EventCallback event_callback_;

    CmdRequestListener* cmd_listener_;
    EventListener* event_listener_;
};

// 指令响应监听器类 
class CNP_API CmdResponseListener : public CustomDataReaderListener<CnpMsg> {
public:
    explicit CmdResponseListener(CallbackType callback) : CustomDataReaderListener<CnpMsg>(callback) {}
};

// 状态监听器类
class CNP_API StatusListener : public CustomDataReaderListener<CnpMsg> {
public:
    explicit StatusListener(CallbackType callback) : CustomDataReaderListener<CnpMsg>(callback) {}
};

// 定义 CNPClient 类
class CNP_API CNPClient {
public:
    explicit CNPClient(CNP_DOMAIN_ID domain, const std::string& serverReqID);
    ~CNPClient();

    CNP_RESULT subscribeStatus(StatusCallback callback);
    CNP_RESULT subscribeEvent(EventCallback callback);
    CNP_RESULT subscribeCmdResponse(CmdResponseCallback callback);

    CNP_RESULT publishCmdRequest(CnpMsg& command_data);
    CNP_RESULT publishEvent(CnpMsg& event_data);  
   

private:
    eprosima::fastdds::dds::DomainParticipant* participant_;

    eprosima::fastdds::dds::Subscriber* status_subscriber_;
    eprosima::fastdds::dds::Subscriber* event_subscriber_;
    eprosima::fastdds::dds::Subscriber* cmd_response_subscriber_;

    eprosima::fastdds::dds::Publisher* cmd_request_publisher_;
    eprosima::fastdds::dds::Publisher* event_publisher_;

    eprosima::fastdds::dds::DataReader* status_reader_;
    eprosima::fastdds::dds::DataReader* event_reader_;
    eprosima::fastdds::dds::DataReader* cmd_response_reader_;

    eprosima::fastdds::dds::DataWriter* cmd_request_writer_;
    eprosima::fastdds::dds::DataWriter* event_writer_;

    eprosima::fastdds::dds::Topic* event_topic_;
    eprosima::fastdds::dds::Topic* cmd_request_topic_;
    eprosima::fastdds::dds::Topic* status_topic_; //2025-03-24 add
    eprosima::fastdds::dds::Topic* cmd_response_topic_; //2025-03-24 add

    std::string serverReqID_; // 新增：客户端请求的服务器ID
    eprosima::fastdds::dds::TypeSupport type_;
    // CnpMsg cmd_msg_;  //cpp实现中没有用上该变量，注释掉

     // 回调函数
    StatusCallback status_callback_;
    EventCallback event_callback_;
    CmdResponseCallback cmd_response_callback_;

    StatusListener* status_listener_;
    CmdResponseListener* cmd_listener_;
    EventListener* event_listener_;
};

 
#endif // CNP_HPP